using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Dapper;
using hao_Common.Dapper.Db;
using hao_Common.Dapper.Query;

namespace hao_Common.Dapper.Repository
{
    /// <summary>
    /// 支持表达式树查询的仓储装饰器
    /// </summary>
    public class QueryableRepository<T> : IGenericRepository<T> where T : class, ISoftDelete
    {
        private readonly IGenericRepository<T> _innerRepository;
        private readonly IDbConnectionFactory _connectionFactory;
        
        public QueryableRepository(IGenericRepository<T> repository, IDbConnectionFactory connectionFactory)
        {
            _innerRepository = repository;
            _connectionFactory = connectionFactory;
        }
        
        // 实现IGenericRepository的所有方法，委托给内部仓储
        public Task<T> GetByIdAsync(object id) => _innerRepository.GetByIdAsync(id);
        public Task<IEnumerable<T>> GetAllAsync() => _innerRepository.GetAllAsync();
        public Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate) => _innerRepository.FindAsync(predicate);
        public Task AddAsync(T entity) => _innerRepository.AddAsync(entity);
        public Task UpdateAsync(T entity) => _innerRepository.UpdateAsync(entity);
        public Task DeleteAsync(object id) => _innerRepository.DeleteAsync(id);
        public Task RemoveAsync(object id) => _innerRepository.RemoveAsync(id);
        public Task<(IEnumerable<T> Items, int TotalCount)> GetPagedAsync(int pageNumber, int pageSize, string orderBy = "Id", bool isDescending = false)
            => _innerRepository.GetPagedAsync(pageNumber, pageSize, orderBy, isDescending);
        
        // 新增的表达式树查询方法
        public IQueryBuilder<T> CreateQueryBuilder(Expression<Func<T, bool>> predicate = null)
        {
            var builder = new ExpressionQueryBuilder<T>();
            if (predicate != null)
            {
                builder.Where(predicate);
            }
            // 自动添加未删除条件
            builder.Where(e => !e.IsDeleted);
            return builder;
        }
        
        public async Task<IEnumerable<T>> QueryAsync(Func<IQueryBuilder<T>, IQueryBuilder<T>> builderAction)
        {
            using var conn = _connectionFactory.CreateConnection();
            var builder = CreateQueryBuilder();
            builder = builderAction(builder);
            return await conn.QueryAsync<T>(builder.GetQuery(), builder.Param);
        }
        
        public async Task<(IEnumerable<T> Items, int TotalCount)> QueryPagedAsync(
            Func<IQueryBuilder<T>, IQueryBuilder<T>> builderAction,
            int pageNumber,
            int pageSize)
        {
            using var conn = _connectionFactory.CreateConnection();
            
            // 创建并配置查询构建器
            var builder = CreateQueryBuilder();
            builder = builderAction(builder);
            
            // 查询总数
            var countBuilder = CreateQueryBuilder();
            countBuilder = builderAction(countBuilder);
            int totalCount = await conn.QuerySingleAsync<int>(countBuilder.GetCountQuery(), countBuilder.Param);
            
            // 应用分页
            builder = builder
                .Skip((pageNumber - 1) * pageSize)
                .Limit(pageSize);
            
            // 查询数据
            var items = await conn.QueryAsync<T>(builder.GetQuery(), builder.Param);
            
            return (items, totalCount);
        }
        
        // 在QueryableRepository类中添加以下方法
        public IDbConnectionFactory GetConnectionFactory()
        {
            return _connectionFactory;
        }
    }
}